With the onset COVID-19 pandemic, many people are creating and sharing visualizations help us understand and map the spread of the virus. I live and work in Chicago, which has been under a “shelter-in-place” order for over a week. Schools have been closed for two weeks. I’ve been busy with the little ones and with work. But I thought I might visualize the spread of COVID-19 in Illinois, which I have not yet seen done.
# Define ggplot theme
theme_set(
theme_minimal() +
theme(
text = element_text(family = "Raleway"),
axis.title.x = element_text(size = 10, hjust = 1),
axis.title.y = element_text(size = 10),
axis.text.x = element_text(size = 6),
axis.text.y = element_text(size = 6),
plot.title = element_text(size = 9, colour = "grey25", face = "bold"),
plot.subtitle = element_text(family = "Lato", size = 8, colour = "grey45"),
plot.caption = element_text(family = "Lato", size = 6, colour = "grey45")
)
)
il <- read_csv("https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv") %>%
filter(state == "Illinois")
# il county census data
il_pop <- get_decennial(geography = "county",
variables = "P001001",
state = "IL",
geometry = TRUE) %>%
janitor::clean_names() %>%
transmute(geoid = geoid,
population = value,
geometry = geometry)
il %>%
filter(cases != 0, date > "2020-02-20") %>%
ggplot(aes(x = date, y = cases, group = county)) +
geom_line(aes(color = county)) +
geom_vline(xintercept = as.Date("2020-03-10"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-21"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-27"), linetype = 2) +
scale_color_viridis_d(guide = FALSE) +annotate("text",
label = "CPS closes schools",
x = as.Date("2020-03-10"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Statewide shelter-in-place",
x = as.Date("2020-03-21"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Lakefront trail\ncloses",
x = as.Date("2020-03-27"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("curve",
x = as.Date("2020-03-16"),
y = 600,
xend = as.Date("2020-03-18"),
yend = (il$cases[il$county == "Cook" & il$date == "2020-03-18"] + 50),
size = 0.25,
curvature = -.3,
arrow = arrow(length = unit(2, "mm"))) +
annotate("text",
label = "Cook County",
x = as.Date("2020-03-16"),
y = 600,
hjust = 1.1,
size = 2.5,
family = "Lato") +
labs(x = "", y = "",
title = "COVID-19 Cases in Illinois",
subtitle = "Number of confirmed cases by county",
caption = "Data from New York Times Covid-19 repository: https://github.com/nytimes/covid-19-data")
il %>%
filter(cases != 0, date > "2020-02-20") %>%
ggplot(aes(x = date, y = cases, group = county)) +
geom_line(aes(color = county)) +
geom_vline(xintercept = as.Date("2020-03-10"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-21"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-27"), linetype = 2) +
scale_color_viridis_d(guide = FALSE) +
scale_y_log10() +
annotate("text",
label = "CPS closes schools",
x = as.Date("2020-03-10"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Statewide shelter-in-place",
x = as.Date("2020-03-21"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Lakefront trail\ncloses",
x = as.Date("2020-03-27"),
y = max(il$cases)*0.5,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("curve",
x = as.Date("2020-03-16"),
y = (il$cases[il$county == "Cook" & il$date == "2020-03-18"] + 300),
xend = as.Date("2020-03-18"),
yend = (il$cases[il$county == "Cook" & il$date == "2020-03-18"] + 10),
size = 0.25,
curvature = -.3,
arrow = arrow(length = unit(2, "mm"))) +
annotate("text",
label = "Cook County",
x = as.Date("2020-03-16"),
y = (il$cases[il$county == "Cook" & il$date == "2020-03-18"] + 300),
hjust = 1.1,
size = 2.5,
family = "Lato") +
labs(x = "", y = "",
title = "COVID-19 Cases in Illinois, Log Scale",
subtitle = "Log (base 10) number of confirmed cases by county",
caption = "Data from New York Times Covid-19 repository: https://github.com/nytimes/covid-19-data")
il_per_cap <-
il %>%
filter(date > "2020-02-20") %>%
complete(county, nesting(date), fill = list(cases = 0, deaths = 0)) %>%
arrange(date, county) %>%
select(-fips) %>%
left_join(il %>% select(county, fips), by = "county") %>%
left_join(il_pop %>% select(geoid, population),
by = c("fips" = "geoid")) %>%
mutate(cases_per = (cases/population) * 10000)
il_per_cap %>%
ggplot(aes(x = date, y = cases_per, group = county)) +
geom_line(aes(color = county)) +
geom_vline(xintercept = as.Date("2020-03-10"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-21"), linetype = 2) +
geom_vline(xintercept = as.Date("2020-03-27"), linetype = 2) +
scale_color_viridis_d(guide = FALSE) +
annotate("text",
label = "CPS closes schools",
x = as.Date("2020-03-10"),
y = max(il_per_cap$cases_per, na.rm = TRUE)*0.95,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Statewide shelter-in-place",
x = as.Date("2020-03-21"),
y = max(il_per_cap$cases_per, na.rm = TRUE)*0.95,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("text",
label = "Lakefront trail\ncloses",
x = as.Date("2020-03-27"),
y = max(il_per_cap$cases_per, na.rm = TRUE)*0.95,
hjust = 1.1,
size = 3,
family = "Lato",
fontface = "italic") +
annotate("segment",
x = as.Date("2020-03-24"),
y = (il_per_cap$cases_per[il_per_cap$county == "Cook" & il_per_cap$date == "2020-03-25"] + 0.5),
xend = as.Date("2020-03-25"),
yend = (il_per_cap$cases_per[il_per_cap$county == "Cook" & il_per_cap$date == "2020-03-25"]),
size = 0.25,
arrow = arrow(length = unit(2, "mm"))) +
annotate("text",
label = "Cook County",
x = as.Date("2020-03-24"),
y = (il_per_cap$cases_per[il_per_cap$county == "Cook" & il_per_cap$date == "2020-03-25"] + 0.55),
hjust = 1.1,
size = 2.5,
family = "Lato") +
annotate("segment",
x = as.Date("2020-03-24"),
y = (il_per_cap$cases_per[il_per_cap$county == "Lake" & il_per_cap$date == "2020-03-25"] + 0.6),
xend = as.Date("2020-03-25"),
yend = (il_per_cap$cases_per[il_per_cap$county == "Lake" & il_per_cap$date == "2020-03-25"]),
size = 0.25,
arrow = arrow(length = unit(2, "mm"))) +
annotate("text",
label = "Lake County",
x = as.Date("2020-03-24"),
y = (il_per_cap$cases_per[il_per_cap$county == "Lake" & il_per_cap$date == "2020-03-25"] + 0.65),
hjust = 1.1,
size = 2.5,
family = "Lato") +
labs(x = "", y = "",
title = "COVID-19 Cases in Illinois",
subtitle = "Number of confirmed cases per 10,000 by county",
caption = "Data from New York Times Covid-19 repository: https://github.com/nytimes/covid-19-data")
il_anim <- il %>%
filter(cases != 0, date > "2020-02-20") %>%
mutate(log_cases = log10(cases)) %>%
left_join(il_pop %>% select(geoid, population),
by = c("fips" = "geoid")) %>%
ggplot() +
geom_sf(data = il_pop, aes(geometry = geometry)) +
geom_sf(aes(geometry = geometry, fill = cases)) +
scale_fill_viridis_c(name = "Cases (logged)") +
labs(x = "", y = "",
title = "COVID-19 Cases in Illinois by County",
subtitle = "{current_frame}",
caption = "Data from New York Times Covid-19 repository: https://github.com/nytimes/covid-19-data") +
transition_manual(date) +
theme(plot.background = element_rect(fill = "antiquewhite2", color = NA),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
animate(il_anim, fps = 5)
il_anim <-
il_per_cap %>%
ggplot() +
geom_sf(data = il_pop, aes(geometry = geometry)) +
geom_sf(aes(geometry = geometry, fill = cases_per), color = NA) +
scale_fill_viridis_c(name = "Cases per 10,000") +
labs(x = "", y = "",
title = "COVID-19 Cases in Illinois by County",
subtitle = "{current_frame}",
caption = "Data from New York Times Covid-19 repository: https://github.com/nytimes/covid-19-data") +
transition_manual(date) +
theme(plot.background = element_rect(fill = "cornsilk2", color = NA),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
animate(il_anim, fps = 5)